package com.herr.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

//《切面》，对《横切关注点》进行抽象而封装的类
@Aspect
@Component
public class LogAspect {

    //定义《切点》，基于注解，凡是使用了该注解的都是《连接点》
    @Pointcut("@annotation(com.herr.aop.Action)")
    public void annotationPointCut(){
    }

    //建言指的就是指拦截到连接点之后要执行的代码，分为前置、后置、环绕、异常、最终。@Before代表前置
    @Before("annotationPointCut()")
    public void after(JoinPoint joinPoint){
        MethodSignature signature=(MethodSignature)joinPoint.getSignature();
        Method method=signature.getMethod();
        Action action=method.getAnnotation(Action.class);
        System.out.println("注解式拦截，"+action.name());
    }

    /**
     * 可使用execution定义基于方法的切点
     * *代表返回任意类型
     * com.herr.aop.MethodService.*代表对应的方法
     * (..)代表使用任意参数
     */
    @Before("execution(* com.herr.aop.MethodService.*(..))")
    public void before(JoinPoint joinPoint){
        MethodSignature signature=(MethodSignature)joinPoint.getSignature();
        Method method=signature.getMethod();
        System.out.println("方法式拦截，"+method.getName());
    }

    //todo

    //https://mp.weixin.qq.com/s/HRL1KvjINayj8mJlqUFqyA Spring Aop 常见注解和执行顺序

}